package com.example.codediff.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import lombok.Data;

/**
 * JAR包比对结果模型类
 * 存储比对过程中发现的差异信息
 */
@Data
public class CompareResult {
    /**
     * 新增的类列表
     * 在新版本中存在但在旧版本中不存在的类
     */
    private List<String> addedClasses = new ArrayList<>();

    /**
     * 删除的类列表
     * 在旧版本中存在但在新版本中不存在的类
     */
    private List<String> removedClasses = new ArrayList<>();

    /**
     * 修改的类列表
     * 在新旧版本中都存在，但内容有变化的类
     */
    private List<String> modifiedClasses = new ArrayList<>();

    /**
     * 类级别的差异信息
     */
    private Map<String, ClassDiff> classDiffs = new HashMap<>();

    /**
     * 类级别的差异信息
     */
    @Data
    public static class ClassDiff {
        private String className;
        private List<MethodDiff> methodDiffs = new ArrayList<>();
    }

    /**
     * 方法级别的差异信息
     */
    @Data
    public static class MethodDiff {
        private String methodName;
        private String methodSignature;
        private Set<String> changes = new HashSet<>();
    }

    /**
     * 添加方法级别的差异信息
     * 
     * @param className 类名
     * @param methodName 方法名
     * @param methodSignature 方法签名
     * @param change 变更信息
     */
    public void addMethodDiff(String className, String methodName, String methodSignature, String change) {
        ClassDiff classDiff = classDiffs.computeIfAbsent(className, k -> {
            ClassDiff diff = new ClassDiff();
            diff.setClassName(k);
            return diff;
        });

        // 查找或创建方法差异
        MethodDiff methodDiff = classDiff.getMethodDiffs().stream()
                .filter(m -> m.getMethodName().equals(methodName))
                .findFirst()
                .orElseGet(() -> {
                    MethodDiff diff = new MethodDiff();
                    diff.setMethodName(methodName);
                    diff.setMethodSignature(methodSignature);
                    classDiff.getMethodDiffs().add(diff);
                    return diff;
                });

        methodDiff.getChanges().add(change);
    }
}
